/* 
 *  Created By: Mike Stevens
 *  Project URL: http://www.codeplex.com/sitesecuritymgmt
 *  License: GNU GPL v2
 *  Copyright (C) 2008 Mike Stevens
 * 
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * 
 */
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;

namespace SiteSecurityManagement.Service.SharePoint
{
    public enum PrincipalTypes
    {
        /// <summary>
        /// User
        /// </summary>
        SPUser, 
        /// <summary>
        /// Sharepoint Group
        /// </summary>
        SPGroup,
        SharePointGroup,
        /// <summary>
        /// Domain Group
        /// </summary>
        SecurityGroup
    }

    abstract class SPObjectSecurity:IDisposable
    {
        #region Members
        #endregion

        #region Constructor/Destructor
        public SPObjectSecurity()
        { }

        public void Dispose()
        {
            GC.SuppressFinalize(this);
        }
        #endregion

        #region Properties
        #endregion

        #region Methods      
        public abstract SPWeb GetSite();

        public abstract bool DoesUserHavePermission(string user, SPBasePermissions permission);

        public abstract bool DoesNotInheritSecurity();

        public abstract void SetInheritance(bool inheritFlag, bool copyPermissions);

        public abstract void SetSecurity(SPGroup group, SPRoleDefinition roleDef);
        
        public abstract void SetSecurity(SPUser user, SPRoleDefinition roleDef);

        public virtual void SetSecurity(string principal, PrincipalTypes principalType, string[] roleDefs)
        {
            foreach (string role in roleDefs)
            {
                SPRoleDefinition roleDef = this.GetRoleDefinition(this.GetSite(), role.Trim());
                if (roleDef != null)
                {
                    if (principalType == PrincipalTypes.SPUser ||
                        principalType == PrincipalTypes.SecurityGroup)
                    {
                        SPUser spuser = this.GetUser(this.GetSite(), principal.Trim());
                        if (spuser != null)
                        {
                            this.SetSecurity(spuser, roleDef);
                        }
                    }
                    else
                    {
                        SPGroup spgroup = this.GetGroup(this.GetSite(), principal.Trim());
                        if (spgroup != null)
                        {
                            this.SetSecurity(spgroup, roleDef);
                        }
                    }
                }
            }
        }

        public abstract void ClearSecurity();
        
        /// <summary>
        /// Get the role definitions for the site.  Returns a string array of role defintions with format id;name;description
        /// </summary>
        /// <returns>String array of role defintions with format id;name;description</returns>
        public string[] GetRoleDefinitions(SPWeb site)
        {
            List<string> roleList = new List<string>();

            SPRoleDefinitionCollection roleDefinitions = site.RoleDefinitions;
            foreach (SPRoleDefinition roleDefinition in roleDefinitions)
            {
                roleList.Add(roleDefinition.Id + ";" + roleDefinition.Name + ";" + roleDefinition.Description);
            }

            return roleList.ToArray();
        }

        public virtual SPRoleDefinition GetRoleDefinition(SPWeb site,string roleName)
        {
            try
            {
                return site.RoleDefinitions[roleName];
            }
            catch
            {
                return null;
            }
        }

        public virtual SPUser GetUser(SPWeb site,string user)
        {
            try
            {
                return site.SiteUsers[user];
            }
            catch 
            {
                return null;
            }
        }

        public virtual SPGroup GetGroup(SPWeb site, string group)
        {
            try
            {
                return site.SiteGroups[group];
            }
            catch
            {
                return null;
            }
        }
        #endregion
    }
}
